package com.hdq.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.hdq.constant.MessageConstant;

import java.util.Date;
import java.util.Map;

public class JwtUtil {
    /**
     * 生成jwt
     * 使用Hs256算法, 私匙使用固定秘钥
     *
     * @param secretKey jwt秘钥
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

//        生成token
        String token = JWT.create()
                .withPayload(claims)
                .withExpiresAt(exp)
                .sign(Algorithm.HMAC256(secretKey));
        return token;
    }

    /**
     * Token解密
     *
     * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @param token     加密后的token
     * @return
     */
    public static Map<String, Claim> parseJWT(String secretKey, String token) {

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secretKey)).build();

        DecodedJWT verify = jwtVerifier.verify(token);

        Map<String, Claim> claims = verify.getClaims();

        return claims;
    }


    public static boolean isTokenExpired(String secretKey,String token){
        try {
            // 创建一个 JWT 验证器
            Algorithm algorithm = Algorithm.HMAC256(secretKey);
            JWTVerifier verifier = JWT.require(algorithm).build();

            // 解析 token
            DecodedJWT decodedJWT = verifier.verify(token);

            // 获取 token 的过期时间
            Date expiration = decodedJWT.getExpiresAt();

            // 判断是否过期
            return expiration.before(new Date());
        } catch (TokenExpiredException e) {
            // Token 已过期
            throw new com.hdq.exception.TokenExpiredException(MessageConstant.EXPIRED_Token);
        } catch (JWTVerificationException e) {
            // Token 无效（如签名错误）
            throw new com.hdq.exception.TokenExpiredException(MessageConstant.ILLEGAL_Token);
        }
    }
}
